import React, { useRef, useState, useEffect } from 'react';
import Recorder from 'js-audio-recorder';
import { Button, message } from 'antd'
import { CaretRightOutlined } from '@ant-design/icons';
import SiriWave from 'siriwave'
import Hls from 'hls.js'
import style from './index.less'

/**
 *  [
 *    {
 *      audio: [ { text: 'xxx', url: '' } ],
 *      media: []
 *    },
 *   ]
 * 
 */

const MIN_LENGTH = 2 // 最低多少个资源开始播放
let currentMediaIndex = 0 // 资源播放下标
let playAudioNum = 0 // 语音播放下标
let current_playFinish: any = null
let imageTimeOut: any = null
let currentAudio: any = null
let audioText_terval: any = null
let is_playFinish: any = null


let mediaPlayingIndex = -1 // 正在播放的资源下标
let audioIndex = 0 // 正在播放语音下标 (整体目录下标)
let currentIdx = -1 // 当前及上一个正在播放下标，-1 为未播放
let mediaAudioIndex = 0 // 当前资源对应语音下标 (audio数组 下标)
let requestAudioIndex = -1 // 语音请求下标
let staticPath = '/static/media' // 资源路径

export default function HomePage() {
  const [showSubtitles, setShowSubtitles] = useState('') // 字幕内容
  const [show, setShow] = useState('none') // none, image, video
  const [imageUrl, setImageUrl] = useState('')

  const [audioTextArray, setAudioTextArray] = useState<any[]>([])

  const audioTextArrayRef = useRef(audioTextArray);

  useEffect(() => {
    audioTextArrayRef.current = audioTextArray;
  }, [audioTextArray.length]);

  const recorderRef = useRef<any>(null)
  const siriWaveRef = useRef<any>(null)
  const waveRef = useRef<any>(null)
  const videoRef = useRef<any>(null);
  const imageRef = useRef<any>(null);

  const init = () => {
    playAudioNum = 0
    setAudioTextArray([])
    mediaAudioIndex = 0
    requestAudioIndex = -1
    currentIdx = -1
    mediaPlayingIndex = -1
    audioIndex = 0
    currentMediaIndex = 0
    window.clearInterval(is_playFinish);
    window.clearInterval(current_playFinish);
    window.clearTimeout(imageTimeOut)
    window.clearInterval(audioText_terval);
    is_playFinish = null
    audioText_terval = null
    current_playFinish = null
    imageTimeOut = null
    setShowSubtitles('')
    setImageUrl('')
    setShow('none')
    currentAudio && currentAudio.pause()
    currentAudio = null
    waveRef.current && waveRef.current.setAmplitude(0.1)
  }

  const send = () => {
    init()

    getText2Text('三大纪律六项注意是什么')
  }

  const playNextMedia = (resource: any[]) => {
    if (currentMediaIndex < resource?.length) {
      const media = resource[currentMediaIndex];
      if (media.digital_file_format.endsWith('.png') || media.digital_file_format.endsWith('.jpg')) {
        setShow('image')
        setImageUrl(`${staticPath}/${media.collection_id}${media.digital_file_format}`)
        imageTimeOut = setTimeout(() => playNextMedia(resource), 5000);
      } else if (media.digital_file_format.endsWith('.m3u8')) {
        setShow('video')
        if (Hls.isSupported()) {
          const hls = new Hls();
          hls.loadSource(`${staticPath}/${media.collection_id}${media.digital_file_format}`);
          hls.attachMedia(videoRef.current);
          hls.on(Hls.Events.MANIFEST_PARSED, function () {
            videoRef.current.play();
          });
        } else if (videoRef.current.canPlayType('application/vnd.apple.mpegurl')) {
          videoRef.current.src = `${staticPath}/${media.collection_id}${media.digital_file_format}`
          videoRef.current.addEventListener('loadedmetadata', function () {
            videoRef.current.play();
          });
        }
        videoRef.current.onended = playNextMedia;
      } else if (media.digital_file_format.endsWith('mp4')) {
        setShow('video')
        videoRef.current.src = `${staticPath}/${media.collection_id}${media.digital_file_format}`
        videoRef.current.onended = playNextMedia;
        videoRef.current.play();
      } else {
        console.warn(`Unsupported media type: ${media.digital_file_format}`);
      }
      currentMediaIndex++;
    } else {
      currentMediaIndex = 0
      setImageUrl('')
      setShow('none')
      window.clearTimeout(imageTimeOut)
    }
  }

  // const playNextSubtitle = () => {
  //   if (currentSubtitleIndex < audioList.length) {
  //     const subtitle = audioList[currentSubtitleIndex];
  //     const audio = new Audio(`${staticPath}/${subtitle.audio}`)
  //     audio.play()
  //     audio.onloadedmetadata = () => {
  //       const audioDuration = audio.duration;
  //       videoRef.current.volume = 0.1; // 将视频音量调至20%
  //       displaySubtitles(subtitle.text, audioDuration, () => {
  //         if (audio.ended) {
  //           videoRef.current.volume = 1.0; // 将视频音量调回到最大
  //           setShowSubtitles(''); // 清空字幕内容
  //           // playNextSubtitle();
  //         }
  //       })
  //     }

  //     currentSubtitleIndex++;
  //   } else {
  //     setShowSubtitles('')
  //   }
  // }

  // const displaySubtitles = (subtitle: string, audioDuration: any, callback: any) => {
  //   const chunks: any[] = [];
  //   for (let i = 0; i < subtitle.length; i += maxSubtitleLength) {
  //     chunks.push(subtitle.substring(i, i + maxSubtitleLength));
  //   }

  //   const chunkDuration = audioDuration / chunks.length;
  //   let chunkIndex = 0;
  //   const displayNextChunk = () => {
  //     if (chunkIndex < chunks.length) {
  //       setShowSubtitles(chunks[chunkIndex])
  //       chunkIndex++;
  //       setTimeout(displayNextChunk, chunkDuration * 1000);
  //     } else if (callback) {
  //       callback();
  //     }
  //   }

  //   displayNextChunk();
  // }

  /**
   * 
   * 以下不动， 对接语音接口
   */

  const getText2Text = async (text: string) => {
    if (!text) {
      return
    }
    let response
    try {
      response = await fetch('http://127.0.0.1:5000/send_message', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ username: 'test', message: text })
      }).then((res) => res.json());
    } catch (error) {
      console.warn(error)
    }
  }

  const openLoop = async (res: any) => {
    for (const num of res?.outline) {
      await fetchData(num)
    }
  }

  const fetchData = async (num: any) => {
    const res = await fetch(`http://127.0.0.1:5000/chat/completions`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ query: num.content })
    })

    let audioText = '';

    const finish = (value: any) => {
      if (audioTextArrayRef.current.findIndex(e => e.audio[0].text === value.audio[0].text) === -1) {
        audioTextArrayRef.current.push(value)
        setAudioTextArray(audioTextArrayRef.current)
      }
    };
    if (res.ok) {
      const reader = res.body?.getReader();
      const decoder = new TextDecoder();
      let mediaAudioArr: any = {
        audio: [],
        media: num?.resources || []
      }
      while (true) {
        // handle time out, will stop if no response in 10 secs
        const content = await reader?.read();
        const text = decoder.decode(content?.value);
        let showAudioText = ''
        let remainAudioText = ''
        let isDone = false // 是否到最后
        let idParagraph = false // 是否段落拆分

        const showObj = JSON.parse(text) || {}
        const contentValue = !!showObj?.output?.choices?.[0]?.message?.content ? showObj?.output?.choices?.[0]?.message?.content : ''
        showAudioText += contentValue

        if (!!showObj?.output?.choices?.[0]?.finish_reason && showObj?.output?.choices?.[0]?.finish_reason === 'stop') {
          isDone = true
        }

        // DataObjArr?.forEach(item => {
        //   let showobj: any
        //   if (item) {
        //     try {
        //       showobj = JSON.parse(item) || {}
        //     } catch (error) {
        //       new Error('解析失败')
        //     }
        //     const content = !!showobj?.output?.choices?.[0]?.message?.content ? showobj?.output?.choices?.[0]?.message?.content : ''
        //     showAudioText += content
        //     if (!!showobj?.output?.choices?.[0]?.finish_reason && showobj?.output?.choices?.[0]?.finish_reason === 'stop') {
        //       isDone = true
        //     }
        //   }
        // })

        const filterList = ["!", "?", ";", "。", "！", "？"]
        const isOver = filterList.findIndex(e => showAudioText.includes(e))
        if (isOver > -1) {
          const index = showAudioText.indexOf(filterList[isOver])
          const start = showAudioText.slice(0, index + 1)
          const end = showAudioText.slice(index + 1)
          audioText += start
          remainAudioText = end
          idParagraph = true
          mediaAudioArr.audio.push({ text: audioText })
          audioText = end || ''
        } else {
          audioText += showAudioText
        }
        const done = isDone || !content || content.done

        if (idParagraph && done) {
          if (audioTextArrayRef.current.findIndex(e => e.audio[0].text === mediaAudioArr.audio[0].text) === -1) {
            audioTextArrayRef.current.push(mediaAudioArr)
          }
          // setAudioTextArray(audioTextArrayRef.current)
          idParagraph = false
          showAudioText = ''
          audioText = remainAudioText
        }
        if (done) {
          break;
        }
      }
      finish(mediaAudioArr);
      audioText_terval = setInterval(() => {
        // if (!audioTextArrayRef.current?.length) {
        //   window.clearInterval(audioText_terval);
        //   audioText_terval = null
        //   return
        // }
        if (mediaAudioIndex < audioTextArrayRef.current[audioIndex].audio.length - 1) {
          if (mediaAudioIndex !== requestAudioIndex) {
            requestAudioIndex = mediaAudioIndex
            onAudio?.(audioTextArrayRef.current[audioIndex], true, false)
          }
        } else {
          window.clearInterval(audioText_terval);
        }
      }, 1000)
    }
  }

  /**
   * 
   * @param content   {audio: [], media: []}
   * @param paragraph 
   * @param done 
   * @returns 
   */
  const onAudio = async (content: any, paragraph: any, done: any) => {
    if (!done) {
      if (paragraph) { // 段落语音
        // 获取语音
        const text = content.audio[mediaAudioIndex].text
        const response: any = await fetch(`http://127.0.0.1:5000/tts`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ text })
        }).then((res) => res.blob())

        const url = URL.createObjectURL(response);
        audioTextArrayRef.current[audioIndex].audio[mediaAudioIndex].url = url

        mediaAudioIndex += 1

        if (!is_playFinish) {
          is_playFinish = setInterval(function () {
            const currentIndex = playAudioNum
            // 新加一个 audioTextArrayRef.current[audioIndex].audio 长度 后才执行语音
            if (currentIndex !== currentIdx && currentIndex < mediaAudioIndex
              // && audioTextArrayRef.current[audioIndex].audio?.length >= MIN_LENGTH
            ) {
              const url = audioTextArrayRef.current[audioIndex].audio[currentIndex]?.url
              waveRef.current && waveRef.current.start()
              waveRef.current && waveRef.current.setAmplitude(1)
              currentAudio = new Audio(url)
              currentAudio.play()
              // 播放语音是，视频音量减小
              videoRef.current.volume = 0.1
              // 当语音播放时，放置对应的字幕
              setShowSubtitles(audioTextArrayRef.current[audioIndex].audio[currentIndex]?.text)
              // 当语音播放时，放对应的资源
              const resources = audioTextArrayRef.current[audioIndex].media
              if (resources?.length && mediaPlayingIndex !== audioIndex) {
                mediaPlayingIndex = audioIndex
                playNextMedia(resources)
              }
              currentIdx = currentIndex
              current_playFinish = setInterval(() => {
                if (currentAudio?.ended) {
                  // 语音结束时，对应字幕关闭
                  setShowSubtitles('')
                  // 当语音播放完时， 视频音量放大
                  videoRef.current.volume = 1
                  playAudioNum = currentIndex + 1
                  window.clearInterval(current_playFinish);
                }
              }, 100)
            }
            if (currentIndex >= audioTextArrayRef.current[audioIndex].audio.length - 1) {
              // 当前audio播放完
              if (audioIndex < audioTextArrayRef.current.length - 1) {
                // 当前audio播放完，播放下一个audio
                if (!currentMediaIndex) {
                  // 资源播放完、语音播放完，播放下一个资源
                  audioIndex += 1
                  mediaAudioIndex = 0
                  requestAudioIndex = -1
                  playAudioNum = 0
                  currentIdx = -1
                }
              }
              if (currentIndex >= audioTextArrayRef.current[audioIndex].audio.length && audioIndex >= audioTextArrayRef.current.length - 1) {
                // 全部播放完
                playAudioNum = 0
                mediaAudioIndex = 0
                requestAudioIndex = -1
                currentIdx = -1
                audioIndex = 0
                mediaPlayingIndex = -1
                window.clearInterval(is_playFinish);
                window.clearInterval(audioText_terval);
                window.clearInterval(current_playFinish);
                audioText_terval = null
                current_playFinish = null
                is_playFinish = null
                waveRef.current && waveRef.current.setAmplitude(0.1)
                init()
              }
            }
          }, 100);
        }
      }
    } else {
      const response: any = await fetch(`http://127.0.0.1:5000/tts`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ text: content })
      }).then((res) => res.blob())
      const url = URL.createObjectURL(response);
      waveRef.current && waveRef.current.start()
      waveRef.current && waveRef.current.setAmplitude(1)
      currentAudio = new Audio(url)
      currentAudio.play()
      // 当语音播放时，放置对应的字幕
      setShowSubtitles(content)
      current_playFinish = setInterval(() => {
        if (currentAudio?.ended) {
          // 语音结束时，对应字幕关闭
          setShowSubtitles('')
          // 当语音播放完时， 视频音量放大
          window.clearInterval(current_playFinish);
          current_playFinish = null
          waveRef.current && waveRef.current.setAmplitude(0.1)
        }
      }, 100)
    }
  }

  // const text2Audio = (text: string) => {
  //   fetch('http://127.0.0.1:7861/api/get_message', {
  //     method: 'POST',
  //     headers: {
  //       'Content-Type': 'application/json'
  //     },
  //     body: JSON.stringify({
  //       text
  //     })
  //   }).then(res => res.blob()).then(response => {
  //     const url = URL.createObjectURL(response);
  //     const audio = new Audio(url);
  //     let currentSubtitleIndex = 0
  //     audio.play();
  //     audio.addEventListener('timeupdate', function () {
  //       var currentTime = audio.currentTime;
  //       var subtitleDuration = 3; // 每行字幕的持续时间（秒）
  //       // 计算应该显示哪一行字幕
  //       var targetIndex = Math.floor(currentTime / subtitleDuration);

  //       // 如果目标索引与当前字幕索引不同，则更新字幕
  //       if (targetIndex !== currentSubtitleIndex) {
  //         currentSubtitleIndex = targetIndex;
  //       }
  //     });

  //   })
  // }


  // const uploadAudio = (blob: any) => {
  //   let mediaSource = new MediaSource();
  //   let audio = new Audio();
  //   audio.src = URL.createObjectURL(mediaSource);
  //   audio.autoplay = true;

  //   mediaSource.addEventListener('sourceopen', sourceOpen);

  //   let sourceBuffer: any
  //   let queue: any[] = [];

  //   function appendNextChunk() {
  //     if (queue.length > 0 && !sourceBuffer.updating) {
  //       sourceBuffer.appendBuffer(queue.shift());
  //     }
  //   }

  //   function text2Audio(text: string) {
  //     fetch('http://127.0.0.1:7861/api/get_message', {
  //       method: 'POST',
  //       headers: {
  //         'Content-Type': 'application/json'
  //       },
  //       body: JSON.stringify({
  //         text
  //       })
  //     }).then(res => res.blob()).then(response => {
  //       const url = URL.createObjectURL(response);
  //       const audio = new Audio(url);
  //       let currentSubtitleIndex = 0
  //       audio.play();
  //       audio.addEventListener('timeupdate', function () {
  //         var currentTime = audio.currentTime;
  //         var subtitleDuration = 3; // 每行字幕的持续时间（秒）
  //         // 计算应该显示哪一行字幕
  //         var targetIndex = Math.floor(currentTime / subtitleDuration);

  //         // 如果目标索引与当前字幕索引不同，则更新字幕
  //         if (targetIndex !== currentSubtitleIndex) {
  //           currentSubtitleIndex = targetIndex;
  //         }
  //       });

  //     })
  //   }

  //   function sourceOpen(event: any) {
  //     sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');
  //     sourceBuffer.addEventListener('updateend', appendNextChunk);

  //     const formData = new FormData();
  //     formData.append('file', blob);

  //     fetch('http://127.0.0.1:23456/voice/asr', {
  //       method: 'POST',
  //       mode: 'cors',
  //       body: formData
  //     }).then((res) => res.json()).then(response => {
  //       text2Audio(response)
  //     })
  //   }
  // }

  // const onKeyUp = (event: KeyboardEvent) => {
  //   if (event.key === 'Control' || event.key === 'Ctrl') {
  //     return
  //     recorderRef.current.stop();
  //     const blob = recorderRef.current.getWAVBlob();
  //     uploadAudio(blob)
  //   }
  // }

  // const onkeyDown = (event: KeyboardEvent) => {
  //   if ((event.key === 'Control' || event.key === 'Ctrl')) {
  //     return
  //     recorderRef.current && recorderRef.current?.start().then(() => {
  //       // 开始录音
  //     }, (error: any) => {
  //       // 出错了
  //     });
  //   }
  // }

  // useEffect(() => {
  //   document.addEventListener('keyup', onKeyUp);
  //   document.addEventListener('keydown', onkeyDown);
  //   return () => {
  //     document.removeEventListener('keyup', onKeyUp);
  //     document.removeEventListener('keydown', onkeyDown);
  //   };
  // }, [onKeyUp, onkeyDown]);


  useEffect(() => {
    recorderRef.current = new Recorder({
      sampleBits: 16,                 // 采样位数，支持 8 或 16，默认是16
      sampleRate: 16000,              // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，我的chrome是48000
      numChannels: 1,                 // 声道，支持 1 或 2， 默认是1
    });
    waveRef.current = new SiriWave({
      container: siriWaveRef.current,
      style: 'ios9',
      autostart: true,
    })
    waveRef.current && waveRef.current.setAmplitude(0.1)

    const script = document.createElement('script');
    script.src = 'https://cdn.socket.io/4.0.0/socket.io.min.js'
    script.async = true;
    script.onload = () => {
      const socket = io('http://127.0.0.1:5000');

      socket.on('connect', () => {
        console.log('Connected to server');
      })

      socket.on('message', (data: any) => {
        if (data?.extra) { // 语音模式
          const res = JSON.parse(data.extra)
          staticPath = res?.resources_abs_path || '/static/media'
          openLoop(res)
        } else { // 闲聊模式
          const contnet = data?.message
          onAudio(contnet, false, true)
        }
      })
    }
    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    }

  }, [])

  return (
    <div className={style.root}>
      <div className={style.wrap}>
        <img ref={e => imageRef.current = e} src={imageUrl} alt="" style={{ display: show === 'image' ? 'block' : 'none' }} />
        <video ref={e => videoRef.current = e} controls={false} style={{ display: show === 'video' ? 'block' : 'none' }} />
        <div ref={e => siriWaveRef.current = e} style={{ width: 500, height: 500, display: show === 'none' ? 'block' : 'none' }}></div>
        <div className={style.subtitles}>
          {showSubtitles}
        </div>
      </div>

      <Button
        type="primary"
        style={{ position: 'absolute', left: '20px', top: '20px' }}
        icon={<CaretRightOutlined />}
        onClick={send}
      />
    </div>
  );
}
